﻿namespace SLControlProvider.Web
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using AssemblyProvider.Web.Entities;
    using AbstraX.ServerInterfaces;
    using System.IO;
    using System.Diagnostics;
    using System.Threading;
    using AbstraX.Contracts;
    using AssemblyProvider;
    using SLControlProvider.Web.Entities;
    using AbstraX.TypeMappings;

    /*
        ControlsRoot
            Control

                ---- Attributes

                        PropertyAttribute

                ---- Operations

                        ConstructorOperation
                        MethodOperation
                        EventOperation

                ---- ChildElements

                        PropertyElement
                        TypeElement
     */

    // http://www.ningzhang.org/2009/01/21/how-to-add-an-toolbox-icon-for-your-silverlight-control/

    [EnableClientAccess()]
    public class SLControlProviderService : DomainService, IAbstraXProviderService
    {
        public IDomainHostApplication DomainServiceHostApplication { get; set; }

        public SLControlsRoot GetSLControlsRoot()
        {
            List<string> controls = new List<string>();

            controls.AddRange(new List<string>() 
            {
                @"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\System.Windows.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Libraries\Client\System.Windows.Controls.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.DataVisualization.Toolkit.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.Input.Toolkit.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.Theming.Toolkit.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.Toolkit.dll",
                @"C:\Program Files (x86)\Microsoft SDKs\Silverlight\v4.0\Toolkit\Apr10\Bin\System.Windows.Controls.Toolkit.Internals.dll",
            });

            var root = DomainServiceHostApplication.AssemblyProviderService.GetAssembliesRoot(controls);

            return new SLControlsRoot(root);
        }

        public string GetRootID()
        {
            return new SLControlsRoot().ID;
        }

        [Query]
        public IQueryable<SLControlAssembly> GetControlAssembliesForControlsRoot(string parentID)
        {
            Debug.WriteLine("Loading assemblies for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLControlAssembly>(this);
            var results = hierarchy.AsQueryable().Where(a => a.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLControl> GetControlsForAssembly(string parentID)
        {
            Debug.WriteLine("Loading types for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLControl>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<Assembly> GetBaseTypesForControl(string parentID)
        {
            Debug.WriteLine("Loading types for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<Assembly>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLPropertyElement> GetPropertyElementsForControl(string parentID)
        {
            Debug.WriteLine("Loading property elements for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLPropertyElement>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLPropertyAttribute> GetPropertyAttributesForControl(string parentID)
        {
            Debug.WriteLine("Loading property attributes for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLPropertyAttribute>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLFieldAttribute> GetFieldAttributesForControl(string parentID)
        {
            Debug.WriteLine("Loading field attributes for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLFieldAttribute>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLOperation> GetOperationsForControl(string parentID)
        {
            Debug.WriteLine("Loading operation for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLOperation>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Query]
        public IQueryable<SLControl> GetControlsForControl(string parentID)
        {
            Debug.WriteLine("Loading base types for '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLControl>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Invoke]
        public void RequestBuild(string id)
        {

        }

        [Query]
        public IQueryable<SLControl> GetTypesForPropertyElement(string parentID)
        {
            Debug.WriteLine("Loading types for property element '" + parentID + "'");

            var hierarchy = new SLControlProviderHierarchy<SLControl>(this, parentID);
            var results = hierarchy.AsQueryable().Where(t => t.ParentID == parentID);

            return results;
        }

        [Invoke]
        public byte[] GetImageForFolder(string folderKey)
        {
            Debug.WriteLine("Loading images for '" + folderKey + "'");

            var stream = this.GetType().Assembly.GetManifestResourceStream(folderKey);
            var bytes = new byte[stream.Length];

            stream.Read(bytes, 0, (int)stream.Length);

            return bytes;
        }

        [Invoke]
        public byte[] GetImageForItemType(string itemTypeName)
        {
            Debug.WriteLine("Loading images for '" + itemTypeName + "'");

            var bytes = new byte[0];

            return bytes;
        }

        [Invoke]
        public byte[] GetImageForUrl(string url)
        {
            Debug.WriteLine("Loading images for '" + url + "'");

            var stream = this.GetType().Assembly.GetManifestResourceStream(url);
            var bytes = new byte[stream.Length];

            stream.Read(bytes, 0, (int)stream.Length);

            return bytes;
        }

        public IBase GenerateByID(string id)
        {
            return AbstraXExtensions.GenerateByID(this, id);
        }

        public ContainerType GetAllowableContainerTypes(string id)
        {
            throw new NotImplementedException();
        }

        public ConstructType GetAllowableConstructTypes(string id)
        {
            throw new NotImplementedException();
        }

        public SortedList<float, IPipelineStep> InitialPipelineSteps
        {
            get
            {
                return null;
            }
        }
    }
}


